package run.graphics;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;

import run.ScenarioManager;
import sound.Recorder;
import sound.SoundListener;

public class DashBoard extends JFrame implements SoundListener {
	
	/**
	 * 
	 */
	private static final long serialVersionUID = -6038846203499133923L;
	
	
	public static final Color ODD_COLOR = Color.white;
	public static final Color EVEN_COLOR = Color.LIGHT_GRAY;
	
	public static final Dimension TRIAL_DIMENSION = new Dimension(200, 50);
	
	public static final int CURVE_BORDERS = 20;
	
	///////////////////////////////////////////////////////////////////////////
	
	private JPanel experimentDataPanel, currentTrialPanel, soundPanel, trialPanel;
	private JLabel participantLabel, trialLabel;
	private JScrollPane listPanel;
	
	private List<Double> levels = Collections.synchronizedList(new ArrayList<Double>());
	private int prevX, prevY;
	
	private int previousTrial = -1;
	
	private ScenarioManager manager;
	
	public DashBoard(ScenarioManager manager) {
		
		super("Dashboard");
		
		this.manager = manager;
		
		setPreferredSize(new Dimension(800, 600));
		setLayout(new BorderLayout(20, 20));
		
		// setResizable(false);
		
		experimentDataPanel = new JPanel();
		// experimentDataPanel.setLayout(new BoxLayout(experimentDataPanel, BoxLayout.X_AXIS));
		JLabel pLabel = new JLabel("Participant nb: ");
		participantLabel = new JLabel();
		JLabel tLabel = new JLabel("Trial nb: ");
		trialLabel = new JLabel();
		experimentDataPanel.add(pLabel);
		experimentDataPanel.add(participantLabel);
		experimentDataPanel.add(tLabel);
		experimentDataPanel.add(trialLabel);
		add(experimentDataPanel, BorderLayout.NORTH);
		
		listPanel = new JScrollPane(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, 
				JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
		// listPanel.setLayout(new BoxLayout(listPanel, BoxLayout.Y_AXIS));
		listPanel.setPreferredSize(new Dimension(250, 500));
		add(listPanel, BorderLayout.EAST);
		
		currentTrialPanel = new JPanel();
		currentTrialPanel.setLayout(new BoxLayout(currentTrialPanel, BoxLayout.Y_AXIS));
		
		soundPanel = new JPanel() {
			
			private static final long serialVersionUID = 3671438188352857490L;
			
			final int d = Recorder.TIME_SAMPLE * (500 - 2 * CURVE_BORDERS) / ScenarioManager.TRIAL_TIME;
			
			@Override
			public void paint(Graphics g) {
				
				super.paint(g);
				final Graphics2D g2d = (Graphics2D) g;
				
				new Thread(new Runnable() {
					@Override
					public void run() {
				
						g2d.setPaint(Color.black);
						
						SwingUtilities.invokeLater(new Runnable() {

							public void run() {
								synchronized (levels) {
									for (Double l : levels) {
										g2d.drawLine(prevX, 
												prevY, 
												prevX + d, 
												getHeight() - 30 * l.intValue() - CURVE_BORDERS);
										prevX += d;
										prevY = getHeight() - 30 * l.intValue() - CURVE_BORDERS;
										// System.out.println(d + ": " + prevX + ", " + prevY);
									}

									prevX = CURVE_BORDERS;
									prevY = soundPanel.getHeight()-CURVE_BORDERS;
								}
							}
						});
					}
		        }).start(); // shit, what. XXX
			}	
		};
		soundPanel.setPreferredSize(new Dimension(500, 200));
		soundPanel.setBackground(Color.white);
		soundPanel.setVisible(true);
		
		prevX = CURVE_BORDERS;
		prevY = soundPanel.getHeight()-CURVE_BORDERS;
		
		trialPanel = new JPanel();
		trialPanel.setPreferredSize(new Dimension(500, 300));
		
		currentTrialPanel.add(soundPanel);
		currentTrialPanel.add(trialPanel);
		add(currentTrialPanel, BorderLayout.CENTER);
		
		setDefaultCloseOperation(EXIT_ON_CLOSE);
		pack();
		setVisible(true);
	}
	
	public void setParticipantNb(int pNb) {
		participantLabel.setText(""+pNb);
	}
	
	public void setTrialNb(int nb) {
		int tNb = nb-1;
		
		trialLabel.setText(""+nb);
		
		if (previousTrial > -1) {
			((JPanel) ((JPanel) listPanel.getViewport().getView()).getComponent(previousTrial))
					.setBorder(BorderFactory.createLineBorder(
							(tNb % 2 == 1 ? EVEN_COLOR : ODD_COLOR), 5));
		}
		
		((JPanel) ((JPanel) listPanel.getViewport().getView()).getComponent(tNb))
				.setBorder(BorderFactory.createLineBorder(Color.red, 5));
		
		listPanel.getVerticalScrollBar().setValue(((JPanel) listPanel.getViewport().getView())
				.getComponent(Math.max(0, tNb-5)).getY());
		
		previousTrial = tNb;
		levels.clear();
	}
	
	public void createTrialList(int nbTrials) {
		
		JPanel container = new JPanel();
		container.setLayout(new BoxLayout(container, BoxLayout.Y_AXIS));
		container.setBackground(Color.red);
		listPanel.setViewportView(container);
		
		for (int t = 1 ; t <= nbTrials ; t++) {
			
			JPanel item = new JPanel(new GridBagLayout());
			item.setSize(new Dimension(200, 50));
			if (t%2 == 1) {
				item.setBackground(EVEN_COLOR);
			} else{
				item.setBackground(ODD_COLOR);
			}
			item.setBorder(BorderFactory.createLineBorder(
					(t % 2 == 1 ? EVEN_COLOR : ODD_COLOR), 5));
			
			JButton replayButton = new JButton("Replay trial"); // TODO action
			JButton markButton = new JButton("Exclude trial"); // TODO action
			JPanel visu = new JPanel();
			visu.setBackground(Color.black);
			visu.setPreferredSize(new Dimension(50, 40));
			JLabel trialNb = new JLabel(""+t+"  ");
			
			GridBagConstraints c = new GridBagConstraints();
			c.gridx = 0;
			c.gridy = 0;
			c.gridheight = 2;
			item.add(trialNb, c);
			c.gridx = 1;
			item.add(visu, c);
			c.gridx = 2;
			c.gridheight = 1;
			item.add(replayButton, c);
			c.gridy = 1;
			item.add(markButton, c);
			
			container.add(item);
			// System.out.println("added " + item.getComponent(0));
			
		}
		
		setTrialNb(1);
		
		listPanel.updateUI();
	}
	
	@Override
	public void levelEvent(double level) {
		levels.add(level);
		soundPanel.repaint();
	}
	
}
